package com.thekernel.youdaoyun.controller;

import com.alibaba.fastjson.JSONObject;
import com.thekernel.youdaoyun.annotation.Log;
import com.thekernel.youdaoyun.bean.User;
import com.thekernel.youdaoyun.exception.MyException;
import com.thekernel.youdaoyun.exception.impl.*;
import com.thekernel.youdaoyun.service.UserService;
import com.thekernel.youdaoyun.util.ResponseUtils;
import com.thekernel.youdaoyun.util.UserUtils;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Objects;

/**
 * @Author TheKernel
 * @Date 2019/9/12 7:50 下午
 * @Version 1.0
 * @Description 暴露给前端的用户接口
 */
@Api(value = "用户Controller")
@Controller
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @ApiIgnore
    @GetMapping("hello")
    public @ResponseBody
    String index() {
        return "Hello User !!!";
    }

    /**
     * 注册用户 API
     *
     * @param data 用户信息(json格式)
     * @return -2: System Error -1: Data Not Found(用户输入信息不足) 0: Username Already Exists 1: Register Success
     */
//    @Log("register_user")
    @ApiOperation(value = "注册用户", notes = "根据用户输入信息注册普通用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "email", value = "用户邮箱", required = true, dataType = "String"),
            @ApiImplicitParam(name = "checkPassword", value = "确认密码", required = true, dataType = "String")
    })
    @PostMapping("register")
    public @ResponseBody
    String registerUser(@RequestBody JSONObject data) throws MyException {
        JSONObject returnData = new JSONObject();
        // 检测用户两次输入密码是否一致
        String password = data.getString("password");
        String checkPassword = data.getString("checkPassword");

        if (!password.equals(checkPassword)) {
            throw new PasswordNotSameException();
        }
        // 通过第一层检验, 生成用户
        data.remove("checkPassword");
        User user = data.toJavaObject(User.class);
        // 注册用户
        int result = this.userService.register(user);
        // Return Body
        if (result == 1) {
            returnData.put("userId", user.getUserId());
            return ResponseUtils.response(ResponseUtils.SUCCESS, "Register Success !!!", returnData);
        } else if (result == -1) {
            throw new DataNotFoundException();
        } else if (result == 0) {
            throw new DataAlreadyExistsException();
        } else {
            throw new SystemErrorException();
        }
    }

    /**
     * 登录用户 API
     *
     * @param user 用户信息(json格式)
     * @return userType / -2: System Error, -1: Data Not Found, 0: Username/password Error
     */
//    @Log("user_login")
    @ApiOperation(value = "用户登录", notes = "根据用户输入信息进行登录并返回用户类型")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "form")
    })
    @PostMapping("login")
    public @ResponseBody
    String userLogin(@RequestBody User user) throws MyException {
        HttpSession session = ((ServletRequestAttributes)
                Objects.requireNonNull(RequestContextHolder.getRequestAttributes()))
                .getRequest()
                .getSession();
        JSONObject returnData = new JSONObject();
        // 用户登录
        User dbUser = this.userService.login(user);
        // Return Body
        long userId = dbUser.getUserId();
        returnData.put("userId", userId);
        returnData.put("isViper", dbUser.getViper());
        session.setAttribute("userId", userId);
        return ResponseUtils.response(ResponseUtils.SUCCESS, "Login Success !!!", returnData);
    }

    /**
     * 获取登录状态的User API
     *
     * @return userId
     */
    @ApiOperation(value = "获取已登录的用户id", notes = "根据登录的用户获取用户的id")
    @GetMapping("sessionUser")
    public @ResponseBody
    String getSessionUsername() throws MyException {
        JSONObject returnData = new JSONObject();
        long userId = UserUtils.checkReturnUserId();
        returnData.put("userId", userId);
        return ResponseUtils.response(ResponseUtils.SUCCESS, "Login Success !!!", returnData);
    }

    /**
     * 更新用户个人信息 API
     *
     * @param user 用户信息(新)
     * @return String 是否成功及信息
     * @throws MyException 非本人操作等
     */
//    @Log("user_update")
    @ApiOperation(value = "更新用户个人信息", notes = "根据登录的用户信息以及用户的输入信息更新用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", dataType = "long", required = true, paramType = "form"),
            @ApiImplicitParam(name = "nickname", value = "用户昵称", dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "avatar", value = "用户头像", dataType = "img", paramType = "form"),
            @ApiImplicitParam(name = "sex", value = "用户性别", dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "signature", value = "个性签名", dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "telephone", value = "用户电话号码", dataType = "long", paramType = "form"),
            @ApiImplicitParam(name = "email", value = "用户邮箱", dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "province", value = "用户地址-省份", dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "city", value = "用户地址-城市", dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "area", value = "用户地址-地区", dataType = "String", paramType = "form")
    })
    @PutMapping("update")
    public @ResponseBody
    String updateUser(@RequestBody User user) throws MyException {
        int result = this.userService.update(user);
        if (result == 1) {
            return ResponseUtils.response(ResponseUtils.SUCCESS, "Update User Information Success", null);
        } else if (result == 0) {
            throw new DataNotFoundException();
        } else {
            throw new SystemErrorException();
        }
    }

    @ApiOperation(value = "用户开通会员", notes = "根据登录的用户信息变为会员")
    @PutMapping("vip")
    public @ResponseBody
    String becomeViper() throws MyException {
        User user = new User();
        user.setUserId(UserUtils.checkReturnUserId());
        int result = this.userService.becomeViper(user);

        if (result == 1) {
            return ResponseUtils.response(ResponseUtils.SUCCESS, "User Become Viper Success", null);
        } else {
            throw new SystemErrorException();
        }
    }

    /**
     * 查看用户个人信息
     *
     * @return User 用户信息
     * @throws MyException 非本人操作等
     */
//    @Log("user_information_query")
    @ApiOperation(value = "查看用户个人信息", notes = "根据登录用户信息查看当前用户信息")
    @GetMapping("view")
    public @ResponseBody
    String viewSelf() throws MyException {
        User user = this.userService.viewSelf();
        if (user != null) {
            JSONObject returnData = new JSONObject();
            returnData.put("data", user);
            return ResponseUtils.response(ResponseUtils.SUCCESS, "View User Success", returnData);
        } else {
            throw new DataNotFoundException();
        }
    }

    @ApiOperation(value = "上传头像", notes = "根据用户登录信息以及图片进行头像更改")
    @PutMapping(value = "avatar", headers = "content-type=multipart/form-data")
    public @ResponseBody
    String updateAvatar(@ApiParam("avatar") MultipartFile avatar) throws MyException {
        if (!avatar.isEmpty()) {
            int result = this.userService.updateAvatar(avatar);
            if (result > 0) {
                return ResponseUtils.response(ResponseUtils.SUCCESS, "Update User Avatar Success", null);
            } else {
                throw new SystemErrorException();
            }
        } else {
            throw new SystemErrorException();
        }
    }

    @ApiOperation(value = "获取头像", notes = "根据用户登录信息以及图片获取头像")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "imgName", value = "用户头像路径", dataType = "String", paramType = "url")
    )
    @GetMapping(value = "/getAvatar/{imgName}", produces = MediaType.IMAGE_JPEG_VALUE)
    public @ResponseBody
    byte[] getImage(@PathVariable(name = "imgName") String imgName) throws IOException {
        String filename = "avatar/" + imgName + ".jpg";
        File file = new File(filename);
        FileInputStream inputStream = new FileInputStream(file);
        byte[] bytes = new byte[inputStream.available()];
        inputStream.read(bytes, 0, inputStream.available());
        return bytes;
    }

    @ApiOperation(value = "修改密码", notes = "根据用户信息修改密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "password", value = "需要修改用户密码", dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "checkPassword", value = "确认密码", dataType = "String", paramType = "form")
    })
    @PutMapping(value = "/password")
    public @ResponseBody
    String updatePassword(@RequestBody JSONObject data) throws MyException {
        String password = (String) data.get("password");
        String checkPassword = (String) data.get("checkPassword");
        long userId = UserUtils.checkReturnUserId();

        if (!password.equals(checkPassword)) {
            throw new PasswordNotSameException();
        }

        User user = new User();
        user.setUserId(userId);
        user.setPassword(password);

        int result = this.userService.updatePassword(user);

        if (result == 1) {
            return ResponseUtils.response(ResponseUtils.SUCCESS, "Update User Password Success", null);
        } else {
            throw new SystemErrorException();
        }
    }

}
